
const { ccclass, property } = cc._decorator;

/**
 * 遮罩橡皮擦
 * 擦除遮罩
 */
@ccclass
export default class EraseMaskCom extends cc.Component {
    private readonly RECT_WIDTH = 60;
    private readonly LINE_RADIUS = 20;
    @property(cc.Mask)
    private mask: cc.Mask = null;//遮罩
    @property(cc.Node)
    private patternNode: cc.Node = null;//图案节点
    @property(cc.Node)
    private eraserNode: cc.Node = null;//橡皮擦
    @property(cc.Node)
    private touchNode: cc.Node = null;//触摸节点
    private pointList: { rect: cc.Rect; isHit: boolean }[] = [];
    private curPoints: cc.Vec2[] = [];
    // 辅助开关，开启则会绘制划开涂层所属的小格子
    // drawSwitch: boolean = true; 

    start() {
        this.init()
        this.touchNode.on(cc.Node.EventType.TOUCH_START, this.touchHandler, this);
        this.touchNode.on(cc.Node.EventType.TOUCH_MOVE, this.touchHandler, this);
        this.touchNode.on(cc.Node.EventType.TOUCH_END, this.touchHandler, this);
        this.touchNode.on(cc.Node.EventType.TOUCH_CANCEL, this.touchHandler, this);
    }
    private touchHandler(evt: cc.Event.EventTouch) {
        switch (evt.type) {
            case cc.Node.EventType.TOUCH_START:
            case cc.Node.EventType.TOUCH_MOVE:
                let local = this.eraserNode.parent.convertToNodeSpaceAR(evt.getLocation())
                this.eraserNode.position = local
                this.clear(cc.v2(local.x, local.y));
                break;
            case cc.Node.EventType.TOUCH_END:
            case cc.Node.EventType.TOUCH_CANCEL:
                this.curPoints = [];
                this.checkProgress();
                break;
        }
    }
    init() {
        this.mask.enabled = true;
        this.mask._graphics.clear();
        this.pointList = [];
        this.curPoints = [];
        // 生成小格子，用来辅助统计涂层的刮开比例
        for (let x = 0; x < this.patternNode.width; x += this.RECT_WIDTH) {
            for (let y = 0; y < this.patternNode.height; y += this.RECT_WIDTH) {
                this.pointList.push({
                    rect: cc.rect(x - this.patternNode.width / 2, y - this.patternNode.height / 2, this.RECT_WIDTH, this.RECT_WIDTH),
                    isHit: false
                });
            }
        }
    }

    clear(pts: cc.Vec2) {
        let eraser = this.mask._graphics;
        const len = this.curPoints.length;
        this.curPoints.push(pts);
        if (len <= 1) {
            // 只有一个点，用圆来清除涂层
            eraser.circle(pts.x, pts.y, this.LINE_RADIUS / 2);
            eraser.fill();
            // 记录点所在的格子
            this.pointList.forEach((item) => {
                if (item.isHit) return;
                const xFlag = pts.x > item.rect.x && pts.x < item.rect.x + item.rect.width;
                const yFlag = pts.y > item.rect.y && pts.y < item.rect.y + item.rect.height;
                if (xFlag && yFlag) item.isHit = true;
            });
        } else {
            // 存在多个点，用线段来清除涂层
            let prevPos = this.curPoints[len - 2];
            let curPos = this.curPoints[len - 1];
            eraser.moveTo(prevPos.x, prevPos.y);
            eraser.lineTo(curPos.x, curPos.y);
            eraser.lineWidth = this.LINE_RADIUS;
            eraser.lineCap = cc.Graphics.LineCap.SQUARE;
            eraser.lineJoin = cc.Graphics.LineJoin.ROUND;
            eraser.strokeColor = cc.color(255, 255, 255, 255);
            eraser.stroke();
            // 记录线段经过的格子
            this.pointList.forEach((item) => {
                item.isHit = item.isHit || cc.Intersection.lineRect(prevPos, curPos, item.rect);
            });
        }
    }
    checkProgress() {
        let hitItemCount = 0;
        let ctx = this.patternNode.getComponent(cc.Graphics);
        this.pointList.forEach((item) => {
            if (!item.isHit) return;
            hitItemCount += 1;
            // if (!this.drawSwitch) return;
            ctx.rect(item.rect.x, item.rect.y, item.rect.width, item.rect.height);
            ctx.fillColor = cc.color(216, 18, 18, 255);
            ctx.fill();
        });


        if (hitItemCount / this.pointList.length >= 0.75) {
            this.mask.enabled = false;
            console.log(`擦拭完成!`)
        }
    }

    onDestroy() {

    }
}
